#include "threadPool.h"
#include <openssl/sha.h>
#define DB_HOST "localhost"
#define DB_USER "root"
#define DB_PASS "root"
#define DB_NAME "network_disk"
#define DB_USER_TABLE "user_table"
#define DB_FILE_TABLE "file_table"
#define MAX_QUERY_LEN 1024

//连接数据库
MYSQL *initDatabaseConnect(){
    MYSQL *conMysql = mysql_init(NULL);
    if(conMysql==NULL){
        DEBUG_PRINT("mysql_init filed\n");
        return NULL;
    }
    MYSQL *ret = mysql_real_connect(conMysql,"localhost","root","root","network_disk",0,NULL,0);
    if(ret==NULL){
        DEBUG_PRINT("%s:%s\n","mysql_real_connect",mysql_error(conMysql));
        return NULL;
    }
    DEBUG_PRINT("connenct network_disk success\n");
    return conMysql;
}

//检查用户是否存在
int userIsExit(MYSQL *mysql,userInfo_t *userInfo,user_t *user){
    char query[1024]={0};
    
    //mysql连接

    snprintf(query,sizeof(query),"select cryptograph from %s where username = '%s'",DB_USER_TABLE,userInfo->userName);
    //进行查询
    int qret = mysql_query(mysql,query);
    if(qret!=0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_query",mysql_error(mysql));
        return -1;
    }

    //查询成功，读类型的指令，执行完之后，还需要调用mysql_store_result
    MYSQL_RES *rows = mysql_store_result(mysql);
    if(!rows){
        fprintf(stderr,"%s:%s\n","mysql_store_result",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_store_result",mysql_error(mysql));
        return -1;
    }

    //获取行的数据，因为用户表的username是唯一键，故如果存在，则必有一行
    int isExit = (int)mysql_num_rows(rows);
    if(isExit>0){
        //用户存在，对比一下密文密码
        //将这行数据读取出来
        MYSQL_ROW row = mysql_fetch_row(rows);
        if(strcmp(userInfo->ciphertext,row[0])==0){
            //用户存在，且密码正确
            return isExit;
        }
        mysql_free_result(rows);
    }
    return 0;
}

//注册用户
int registerUser(MYSQL *mysql,userInfo_t *userInfo,user_t *user){
    char query[1024]={0};
    snprintf(query,sizeof(query),"insert into %s (username,salt,cryptograph) values ('%s','%s','%s')",
             DB_USER_TABLE,userInfo->userName,user->salt,userInfo->ciphertext);
    int qret = mysql_query(mysql,query);
    if(qret!=0){
        //注册失败
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_query",mysql_error(mysql));
        return -1;
    }
    //注册成功
    //新增文件元信息表，filename 
    bzero(query,sizeof(query));
    snprintf(query,sizeof(query),"insert into %s (filename,username,parent_id,hash_sha1,path,type,filesize)"
             "values ('%s','%s',%d,'%s','%s','%c',%lld)",DB_FILE_TABLE,"/",userInfo->userName,-1,"000","/",'d',4096LL);

    qret = mysql_query(mysql,query);
    if(qret!=0){
        //文件信息表初始化失败
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_query,DB_FILE_TABLE",mysql_error(mysql));
        return -1;
    }
    //注册成功
    //初始化pwd的值
    bzero(query,sizeof(query));
    snprintf(query,sizeof(query),"select fid from %s where username = '%s' and parent_id = %d",DB_FILE_TABLE,userInfo->userName,-1);

    qret = mysql_query(mysql,query);
    if(qret!=0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_query,DB_FILE_TABLE/fid/pwd",mysql_error(mysql));
        return -1;
    }

    MYSQL_RES *rows = mysql_store_result(mysql);
    if(!rows){
        fprintf(stderr,"%s:%s\n","mysql_store_result",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_store_result",mysql_error(mysql));
        return -1;
    }

    int isExit = mysql_num_rows(rows);
    if(isExit>0){
        //读出这一行的数据
        MYSQL_ROW row = mysql_fetch_row(rows);
        //将fid即文件元信息表的主键赋值给pwd
        user->pwd = atoi(row[0]);
        DEBUG_PRINT("user->pwd = %d\n",user->pwd);
    }
    return 0;

}
//查找盐值
int userSalt(MYSQL *mysql,userInfo_t *userInfo,user_t *user){
    char query[1024]={0};
    
    //mysql连接

    snprintf(query,sizeof(query),"select salt from %s where username = '%s'",DB_USER_TABLE,userInfo->userName);
    //进行查询
    int qret = mysql_query(mysql,query);
    if(qret!=0){
        fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_query",mysql_error(mysql));
        return -1;
    }

    //查询成功，读类型的指令，执行完之后，还需要调用mysql_store_result
    MYSQL_RES *rows = mysql_store_result(mysql);
    if(!rows){
        fprintf(stderr,"%s:%s\n","mysql_store_result",mysql_error(mysql));
        DEBUG_PRINT("%s:%s\n","mysql_store_result",mysql_error(mysql));
        return -1;
    }

    //获取行的数据，因为用户表的username是唯一键，故如果存在，则必有一行
    int isExit = (int)mysql_num_rows(rows);
    if(isExit>0){
        //用户存在，对比一下密文密码
        //将这行数据读取出来
        MYSQL_ROW row = mysql_fetch_row(rows);
        memcpy(user->salt,row[0],strlen(row[0]));
        DEBUG_PRINT("user.salt = %s\n",user->salt);
        mysql_free_result(rows);
    }
    return 0;
}
// 生成基于用户名和密码的Token
char* generate_token(const char* username, const char* password) {
    //计算拼接后的字符串长度
    size_t combined_len = strlen(username) + strlen(password);
    char* combined =(char *)malloc(combined_len + 1); // +1 for null terminator

    //拼接用户名和密码
    strcpy(combined, username);
    strcat(combined, password);

    //计算SHA1哈希
    unsigned char hash[SHA_DIGEST_LENGTH]; // SHA_DIGEST_LENGTH=20
    SHA1((unsigned char*)combined, combined_len, hash);
    free(combined);

    //将二进制哈希转换为十六进制字符串
    char* token = (char *)malloc(SHA_DIGEST_LENGTH * 2 + 1);
    for(int i = 0; i < SHA_DIGEST_LENGTH; i++) {
        sprintf(&token[i*2], "%02x", hash[i]);
    }
    token[SHA_DIGEST_LENGTH * 2] = '\0';

    return token;
}


